"""
@Author：WangYuXiang
@E-mile：Hill@3io.cc
@CreateTime：2021/3/24 16:34
@DependencyLibrary：无
@MainFunction：无
@FileDoc：
    view.py
    文件说明
@ChangeHistory:
    datetime action why
    example:
    2021/3/24 16:34 change 'Fix bug'

"""
import datetime

import jwt

from common.auth.models import UserModel
from common.auth.serializers import AdminSiteLoginByAPSerializer, AdminSiteLoginByTRSerializer
from common.utils.authentication import TemporaryTokenAuthenticate
from sanic_rest_framework.status import HttpStatus
from sanic_rest_framework.views import GeneralView


class LoginByAP(GeneralView):
    """
    使用 account 和 password 登录
    还需要继续选择 Role
    """

    async def post(self, request, *args, **kwargs):
        ap_login = AdminSiteLoginByAPSerializer(data=request.data)
        if not await ap_login.is_valid():
            return self.error_json_response(data=ap_login.errors, http_status=HttpStatus.HTTP_200_OK)

        data = ap_login.validated_data
        account = data.get('account')
        password = data.get('pwd')
        user = await UserModel.filter(account=account).first()
        if not user:
            return self.error_json_response(msg='账号或密码错误')
        if not user.check_password(password):
            return self.error_json_response(msg='账号或密码错误')
        if not user.is_active:
            return self.error_json_response(msg='账号已被封禁，请联系管理员')
        user.last_login_datetime = user.login_datetime
        user.login_datetime = datetime.datetime.now()
        await user.save()
        res_data = await AdminSiteLoginByAPSerializer(instance=user).data
        token = self.general_temporary_token(user)
        res_data.update({
            'token': token,
        })
        return self.success_json_response(data=res_data)

    def general_temporary_token(self, user):
        """生成临时Token"""
        token_secret = self.app.config.TOKEN_SECRET
        data = {
            'user_id': user.pk,
            'role_id': None,
            "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=30),
            'iat': datetime.datetime.now(),  # 开始时间
            'iss': user.account
        }
        return jwt.encode(data, token_secret, algorithm='HS256')


class LoginByTR(GeneralView):
    authentication_classes = (TemporaryTokenAuthenticate,)

    async def post(self, request, *args, **kwargs):
        tr_login = AdminSiteLoginByTRSerializer(data=request.data, context={'view': self, 'request': request})
        if not await tr_login.is_valid():
            return self.error_json_response(data=tr_login.errors, http_status=HttpStatus.HTTP_200_OK)

        data = tr_login.validated_data
        user = request.user
        role_id = data.get('role_id')
        user.now_role_id = role_id
        token = self.general_token(user, role_id)
        await user.save()
        permissions = await user.permissions_code()

        return self.success_json_response(data={
            'token': token,
            'user_info': {
                'account': user.account,
                'nickname': user.nickname,
            },
            'roleSign': role_id,
            'permissions': permissions
        })

    def general_token(self, user, role_id):
        """生成长效Token"""
        token_secret = self.app.config.TOKEN_SECRET
        data = {
            'user_id': user.pk,
            'role_id': role_id,
            "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=60 * 60 * 24 * 7),
            'iat': datetime.datetime.now(),  # 开始时间
            'iss': user.account
        }
        return jwt.encode(data, token_secret, algorithm='HS256')
